// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.kcvehicle;

import static java.util.Objects.requireNonNull;
import static org.opentcs.util.Assertions.checkInRange;

import jakarta.inject.Inject;
import org.opentcs.data.model.Vehicle;
import org.opentcs.drivers.vehicle.VehicleCommAdapterDescription;
import org.opentcs.drivers.vehicle.VehicleCommAdapterFactory;

/**
 * A factory for loopback communication adapters (virtual vehicles).
 */
public class KCLoopbackCommunicationAdapterFactory
    implements
      VehicleCommAdapterFactory {

  /**
   * The adapter components factory.
   */
  private final KCLoopbackAdapterComponentsFactory adapterFactory;


  /**
   * Indicates whether this component is initialized or not.
   */
  private boolean initialized;

  /**
   * Creates a new factory.
   *
   * @param componentsFactory The adapter components factory.
   */
  @Inject
  public KCLoopbackCommunicationAdapterFactory(
      KCLoopbackAdapterComponentsFactory componentsFactory
  ) {
    this.adapterFactory = requireNonNull(componentsFactory, "componentsFactory");
  }

//  @Inject
//  public KCLoopbackCommunicationAdapterFactory(
//      KCCommunicationFactory communicationFactory
//  ) {
//    this.kccommunicationFactory = requireNonNull(communicationFactory, "kccommunicationFactory");
//  }

//  /**
//   * Creates a new factory.
//   * @param udpService The adapter components factory.
//   */
//  @Inject
//  public KCLoopbackCommunicationAdapterFactory(UDPService udpService) {
//    this.udpService = requireNonNull(udpService, "udpService");
//  }

  @Override
  public void initialize() {
    //有几个适配器，就会初始化几次
    //System.out.println("KCLoopbackCommunicationAdapterFactory.initialize");
    if (isInitialized()) {
      return;
    }
    initialized = true;
  }

  @Override
  public boolean isInitialized() {
    return initialized;
  }

  @Override
  public void terminate() {
    if (!isInitialized()) {
      return;
    }
    initialized = false;
  }

  @Override
  public VehicleCommAdapterDescription getDescription() {
    return new KCLoopbackCommunicationAdapterDescription();
  }

  //校验在界面上 有没有设置 给小车设置 ip 和 port
  //注意：在页面上 要设置 ip 和 port，不然加载不到 这个驱动,这里return 的是false
  @Override
  public boolean providesAdapterFor(Vehicle vehicle) {
    requireNonNull(vehicle, "vehicle");
    try {
      checkInRange(Integer.parseInt(vehicle.getProperty("port")), 1024, 65535);
      if (vehicle.getProperty("ip") == null ||
          vehicle.getProperty("port") == null ||
          vehicle.getProperty("bindPort") == null||
          vehicle.getProperty("commName") == null
      ) {
        return false;
      }

    } catch (IllegalArgumentException exc) {
      return false;
    }
    return true;
  }

  @Override
  public KCLoopbackCommunicationAdapter getAdapterFor(Vehicle vehicle) {
    requireNonNull(vehicle, "vehicle");
    if (!providesAdapterFor(vehicle)) {
      return null;
    }

    KCLoopbackCommunicationAdapter adapter = adapterFactory.createLoopbackCommAdapter(vehicle);
    adapter.getProcessModel().setIp(vehicle.getProperty("ip"));
    adapter.getProcessModel().setPort(Integer.parseInt(vehicle.getProperty("port")));

    return adapter;
  }
}
